package com.mioto.ld.exception;

import cn.hutool.core.exceptions.ValidateException;
import com.mioto.ld.result.ResultData;
import com.mioto.ld.result.SystemTip;
import com.mioto.ld.utils.ResultUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.validation.BindException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.method.HandlerMethod;

import javax.servlet.http.HttpServletResponse;

/**
 * @author mioto-qinxj
 * @date 2024/4/11
 * @desc 自定义异常处理
 */

@Slf4j
@ControllerAdvice
public class BasicExceptionHandler {

    @ExceptionHandler
    public void handler(Exception e, HandlerMethod handlerMethod, HttpServletResponse response) {
        writeResultData(new BasicException(SystemTip.SYSTEM_ERROR).toResultData(),response);
        log.error("{} - {}() handler error", handlerMethod.getBeanType(), handlerMethod.getMethod().getName(), e);
    }

    /**
     * 系统自定义异常
     */
    @ExceptionHandler({BasicException.class})
    public void basicExceptionHandler(BasicException e, HandlerMethod handlerMethod, HttpServletResponse response) {
        writeResultData(e.toResultData(),response);
    }

    /**
     * hutool字段验证失败异常
     */
    @ExceptionHandler({ValidateException.class})
    public void validateExceptionHandler(ValidateException e, HandlerMethod handlerMethod, HttpServletResponse response) {
        writeResultData(ResultData.result(SystemTip.PARAM_VALID_FAIL,e.getMessage()),response);
    }

    /**
     * 使用hibernate注解做参数验证时异常
     */
    @ExceptionHandler({BindException.class})
    public void bindExceptionHandler(BindException e, HandlerMethod handlerMethod, HttpServletResponse response) {
        writeResultData(ResultData.result(SystemTip.PARAM_VALID_FAIL,e.getBindingResult().getAllErrors().get(0).getDefaultMessage()),response);
    }

    /**
     * 违反数据库某字段唯一约束
     */
    @ExceptionHandler({DuplicateKeyException.class})
    public void duplicateKeyExceptionHandler(DuplicateKeyException e, HandlerMethod handlerMethod, HttpServletResponse response){
        writeResultData(ResultData.result(SystemTip.DUPLICATE_KEY_ERROR,e.getCause().getMessage()),response);
        log.error("{} - {}() 违反数据库字段唯一约束 :{}", handlerMethod.getBeanType(), handlerMethod.getMethod().getName(), e.getCause().getMessage());
    }

    private void writeResultData(ResultData resultData,HttpServletResponse response){
        ResultUtil.responseJson(response, resultData);
    }
}
